package pe.cliente.proyecto.core.daobase.impl;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pe.adra.core.bean.SuportEntidad;
import pe.adra.core.dao.ext.QueryUtil;
import pe.adra.util.constantes.ConstantesUtil;
import pe.adra.util.exception.DAOException;
import pe.adra.util.text.Util;
import pe.adra.util.validate.ValidateUtil;
import pe.cliente.proyecto.core.daobase.ResponsableDAOBase;
import pe.cliente.proyecto.dominio.Responsable;

public class ResponsableDAOBaseImpl implements ResponsableDAOBase {

	private static final Logger logger = LoggerFactory.getLogger(ResponsableDAOBaseImpl.class);
	private EntityManager entityManager = null;
	private Query qy = null;
	public ResponsableDAOBaseImpl(EntityManager entityManager) {
			this.entityManager = entityManager;
	}
	
	public int countListaResponsable( Responsable filtro ) throws DAOException {
		int count = 0;
		StringBuffer strbfSqlQuery = new StringBuffer();
		strbfSqlQuery.append(SQL_QUERY_COUNT);
		procesarConsulta(filtro, strbfSqlQuery);
		count = (Integer) qy.getSingleResult();
		return count;
	}

	
	public int countListaResponsable( Responsable filtro, Date finit, Date ffin ) throws DAOException{
		int count = 0;
		StringBuffer strbfSqlQuery = new StringBuffer();
		strbfSqlQuery.append(SQL_QUERY_COUNT);
		procesarConsulta(filtro, finit, ffin, strbfSqlQuery);
		count = (Integer) qy.getSingleResult();
		return count;
	}

	@SuppressWarnings("unchecked")
	public List<Responsable> getListaResponsable( Responsable filtro, int inicio, int fin, String strSort, String strOrder, SuportEntidad... innerjoin ) throws DAOException {
		StringBuffer strbfSqlQuery = new StringBuffer();
		strbfSqlQuery.append(SQL_QUERY);
		procesarConsulta(filtro, strbfSqlQuery, innerjoin);
		QueryUtil.setPaginador(qy, inicio, fin);
		QueryUtil.setOrder(strbfSqlQuery, strSort, strOrder);
		List<Responsable> p = qy.getResultList();
		return p;
	}

	@SuppressWarnings("unchecked")
	public List<Responsable> getListaResponsable( Responsable filtro, Date finit, Date ffin, int inicio, int fin, String strSort, String strOrder, SuportEntidad... innerjoin ) throws DAOException {
		StringBuffer strbfSqlQuery = new StringBuffer();
		strbfSqlQuery.append(SQL_QUERY);
		procesarConsulta(filtro, finit, ffin, strbfSqlQuery, innerjoin);
		QueryUtil.setPaginador(qy, inicio, fin);
		QueryUtil.setOrder(strbfSqlQuery, strSort, strOrder);
		List<Responsable> p = qy.getResultList();
		return p;
	}


	@SuppressWarnings("unchecked")
	public List<Responsable> getCboResponsable() throws DAOException{
		StringBuffer strbfSqlQuery = new StringBuffer();
		strbfSqlQuery.append(SQL_QUERY_CBO);
		Responsable filt = new Responsable();
		filt.setActivo(true);
		procesarConsulta(filt, strbfSqlQuery);
		QueryUtil.setOrder(strbfSqlQuery, CAMPO_ID, QueryUtil.SQL_ASC);
		List<Responsable> p = qy.getResultList();
		return p;
	}

	@SuppressWarnings("unchecked")
	public List<Responsable> getCboResponsable( Responsable filtro ) throws DAOException {
		StringBuffer strbfSqlQuery = new StringBuffer();
		strbfSqlQuery.append(SQL_QUERY_CBO);
		procesarConsulta(filtro, strbfSqlQuery);
		QueryUtil.setOrder(strbfSqlQuery, CAMPO_ID, QueryUtil.SQL_ASC);
		List<Responsable> p = qy.getResultList();
		return p;
	}

	@SuppressWarnings("unchecked")
	public List<Responsable> getResponsablePorID( Integer[] ids , String tipo , SuportEntidad innerjoin ) throws DAOException {
		StringBuffer strbfSqlQuery = new StringBuffer();
		if (tipo.equals(QueryUtil.LISTA_LIMItADA_CBO)) {
				strbfSqlQuery.append(SQL_QUERY_CBO);
		} else if (tipo.equals(QueryUtil.LISTA_COMPLETA)) {
				strbfSqlQuery.append(SQL_QUERY);
		}
		Responsable filt = new Responsable();
		filt.setActivo(true);
		procesarConsulta(filt, ids, strbfSqlQuery, innerjoin);
		QueryUtil.setOrder(strbfSqlQuery, CAMPO_ID, QueryUtil.SQL_ASC);
		List<Responsable> p = qy.getResultList();
		return p;
	}

	private void setValues(Responsable filtro, StringBuffer strbfSqlQuery, SuportEntidad... innerjoin) {;
		QueryUtil.establecerCondicionInnerJoins(strbfSqlQuery, innerjoin);
		Util.quitarUltimoAND(strbfSqlQuery, QueryUtil.SQL_AND);
		QueryUtil.establecerCondicion(strbfSqlQuery, (QueryUtil.SQL_SEA + CAMPO_ID +  QueryUtil.SQL_EQ  + QueryUtil.SQL_FILTRO + CAMPO_ID), filtro.getId());
		QueryUtil.establecerCondicion(strbfSqlQuery, (QueryUtil.SQL_SEA + CAMPO_NOMBRE +  QueryUtil.SQL_LIKE  + QueryUtil.SQL_FILTRO + CAMPO_NOMBRE), filtro.getNombre());
		QueryUtil.establecerCondicion(strbfSqlQuery, (QueryUtil.SQL_SEA + CAMPO_UUID +  QueryUtil.SQL_LIKE  + QueryUtil.SQL_FILTRO + CAMPO_UUID), filtro.getUuid());
		QueryUtil.establecerCondicion(strbfSqlQuery, (QueryUtil.SQL_SEA + CAMPO_FECHAREGISTRO +  QueryUtil.SQL_EQ  + QueryUtil.SQL_FILTRO + CAMPO_FECHAREGISTRO), filtro.getFechaRegistro());
		QueryUtil.establecerCondicion(strbfSqlQuery, (QueryUtil.SQL_SEA + CAMPO_FECHAACTUALIZADA +  QueryUtil.SQL_EQ  + QueryUtil.SQL_FILTRO + CAMPO_FECHAACTUALIZADA), filtro.getFechaActualizada());
		QueryUtil.establecerCondicion(strbfSqlQuery, (QueryUtil.SQL_SEA + CAMPO_ACTIVO +  QueryUtil.SQL_EQ  + QueryUtil.SQL_FILTRO + CAMPO_ACTIVO), filtro.getActivo());
		QueryUtil.establecerCondicion(strbfSqlQuery, (QueryUtil.SQL_SEA + CAMPO_CODIGOUSUARIO +  QueryUtil.SQL_LIKE  + QueryUtil.SQL_FILTRO + CAMPO_CODIGOUSUARIO), filtro.getCodigoUsuario());
		if (logger.isDebugEnabled()) {
			logger.debug("strbfSqlQuery:" + strbfSqlQuery.toString());
		}
	}

	private void setFiltroEntidad(Responsable filtro, SuportEntidad... innerjoin) {
		QueryUtil.establecerInnerJoinsParam(qy, innerjoin);
		QueryUtil.establecerParam(qy, CAMPO_ID, filtro.getId());
		QueryUtil.establecerParam(qy, CAMPO_NOMBRE, filtro.getNombre() , true, true );
		QueryUtil.establecerParam(qy, CAMPO_UUID, filtro.getUuid() , true, true );
		QueryUtil.establecerParam(qy, CAMPO_FECHAREGISTRO, filtro.getFechaRegistro());
		QueryUtil.establecerParam(qy, CAMPO_FECHAACTUALIZADA, filtro.getFechaActualizada());
		QueryUtil.establecerParam(qy, CAMPO_ACTIVO, filtro.getActivo());
		QueryUtil.establecerParam(qy, CAMPO_CODIGOUSUARIO, filtro.getCodigoUsuario() , true, true );
		if (logger.isDebugEnabled()) {
			QueryUtil.printParameterQuery(qy);
		}
	}

	private void procesarConsulta(Responsable filtro, StringBuffer strbfSqlQuery, SuportEntidad... innerjoin) {
		procesarConsulta(filtro, null, null, strbfSqlQuery, innerjoin);
	}
	 private void procesarConsulta(Responsable filtro, Date finit, Date ffin, StringBuffer strbfSqlQuery, SuportEntidad... innerjoin) {
		if (ValidateUtil.isNotNull(filtro)) {
			if (ValidateUtil.isNotNull(finit) || ValidateUtil.isNotNull(ffin)) {
				setValues(filtro, finit, ffin, strbfSqlQuery, innerjoin);
				qy = getEntityManager().createQuery(strbfSqlQuery.toString());
				setFiltroEntidad(filtro, finit, ffin, innerjoin);
			} else {
				setValues(filtro, strbfSqlQuery, innerjoin);
				qy = getEntityManager().createQuery(strbfSqlQuery.toString());
				setFiltroEntidad(filtro, innerjoin);
			}
		}
		if (logger.isDebugEnabled()) {
			logger.debug("strbfSqlQuery:" + strbfSqlQuery.toString());
		}
	}

	private void procesarConsulta(Responsable objEntidad, Integer[] ids, StringBuffer strbfSqlQuery, SuportEntidad... innerjoin) {
		setValues(objEntidad, ids, strbfSqlQuery, innerjoin); 
		qy = getEntityManager().createQuery(strbfSqlQuery.toString());
		setFiltroEntidad(objEntidad, ids, innerjoin); 
	}

	private void setValues(Responsable objEntidad, Integer[] ids, StringBuffer strbfSqlQuery, SuportEntidad... innerjoin) {
		setValues(objEntidad, strbfSqlQuery, innerjoin);
		QueryUtil.establecerCondicionIN(strbfSqlQuery, (QueryUtil.SQL_SEA +  CAMPO_ID + QueryUtil.SQL_EQ + QueryUtil.SQL_FILTRO + CAMPO_ID), Arrays.asList(ids)); 
	}

	private void setValues(Responsable filtro, Date finit, Date ffin, StringBuffer strbfSqlQuery, SuportEntidad... innerjoin) {
		QueryUtil.establecerCondicion(strbfSqlQuery, (QueryUtil.SQL_SEA + CAMPO_FECHAREGISTRO + QueryUtil.SQL_MENOS + QueryUtil.SQL_FILTRO + CAMPO_FECHAREGISTRO + QueryUtil.TOKEMN1 ), finit);
		QueryUtil.establecerCondicion(strbfSqlQuery, (QueryUtil.SQL_SEA + CAMPO_FECHAREGISTRO + QueryUtil.SQL_MAS + QueryUtil.SQL_FILTRO + CAMPO_FECHAREGISTRO + QueryUtil.TOKEMN2), ffin);
		setValues(filtro, strbfSqlQuery, innerjoin);
	}

	private void setFiltroEntidad(Responsable filtro, Date finit, Date ffin, SuportEntidad... innerjoin) {;
		QueryUtil.establecerParam(qy, CAMPO_FECHAREGISTRO + QueryUtil.TOKEMN1 , finit);
		QueryUtil.establecerParam(qy, CAMPO_FECHAREGISTRO + QueryUtil.TOKEMN2 , ffin);
		setFiltroEntidad(filtro, innerjoin);
	}

	private void setFiltroEntidad(Responsable objEntidad, Integer[] ids, SuportEntidad... innerjoin) { 
		QueryUtil.establecerParamIN(qy, CAMPO_ID, Arrays.asList(ids)); 
		setFiltroEntidad(objEntidad, innerjoin); 
	}


	public ResponsableDAOBaseUtil setQuery() {
		return new ResponsableDAOBaseUtil();
	}

	public class ResponsableDAOBaseUtil{

		private StringBuffer strBuffer;
		private Responsable filtro;
		private Query query = null;
		private Date frinit = null;
		private Date frfin = null;
		private Date fainit = null;
		private Date fafin = null;
		private void createBuffer() {
			if (ValidateUtil.isNull(strBuffer)) {
				strBuffer = new StringBuffer();
				strBuffer.append(SQL_QUERY);
				filtro = new Responsable();
			}
		
		}
		
		public ResponsableDAOBaseUtil setId( Long  id ){
			createBuffer();
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_ID +  QueryUtil.SQL_EQ  + QueryUtil.SQL_FILTRO + CAMPO_ID), id);
			filtro.setId(id);
			return this;
		}
		public ResponsableDAOBaseUtil setNombre( String  nombre ){
			createBuffer();
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_NOMBRE +  QueryUtil.SQL_LIKE  + QueryUtil.SQL_FILTRO + CAMPO_NOMBRE), nombre);
			filtro.setNombre(nombre);
			return this;
		}
		public ResponsableDAOBaseUtil setUuid( String  uuid ){
			createBuffer();
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_UUID +  QueryUtil.SQL_LIKE  + QueryUtil.SQL_FILTRO + CAMPO_UUID), uuid);
			filtro.setUuid(uuid);
			return this;
		}
		public ResponsableDAOBaseUtil setFechaRegistro( Date  fechaRegistro ){
			createBuffer();
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_FECHAREGISTRO +  QueryUtil.SQL_EQ  + QueryUtil.SQL_FILTRO + CAMPO_FECHAREGISTRO), fechaRegistro);
			filtro.setFechaRegistro(fechaRegistro);
			return this;
		}
		public ResponsableDAOBaseUtil setFechaActualizada( Date  fechaActualizada ){
			createBuffer();
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_FECHAACTUALIZADA +  QueryUtil.SQL_EQ  + QueryUtil.SQL_FILTRO + CAMPO_FECHAACTUALIZADA), fechaActualizada);
			filtro.setFechaActualizada(fechaActualizada);
			return this;
		}
		public ResponsableDAOBaseUtil setActivo( Boolean  activo ){
			createBuffer();
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_ACTIVO +  QueryUtil.SQL_EQ  + QueryUtil.SQL_FILTRO + CAMPO_ACTIVO), activo);
			filtro.setActivo(activo);
			return this;
		}
		public ResponsableDAOBaseUtil setCodigoUsuario( String  codigoUsuario ){
			createBuffer();
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_CODIGOUSUARIO +  QueryUtil.SQL_LIKE  + QueryUtil.SQL_FILTRO + CAMPO_CODIGOUSUARIO), codigoUsuario);
			filtro.setCodigoUsuario(codigoUsuario);
			return this;
		}
		
		private void setFiltros() {
			Util.quitarUltimoAND(strBuffer, QueryUtil.SQL_AND);
			if (logger.isDebugEnabled()){
				logger.debug("strBuffer:" + strBuffer.toString());
			}
			query = entityManager.createQuery(strBuffer.toString());
			QueryUtil.establecerParam(query, CAMPO_ID, filtro.getId());
			QueryUtil.establecerParam(query, CAMPO_NOMBRE, filtro.getNombre() , true, true );
			QueryUtil.establecerParam(query, CAMPO_UUID, filtro.getUuid() , true, true );
			QueryUtil.establecerParam(query, CAMPO_FECHAREGISTRO, filtro.getFechaRegistro());
			QueryUtil.establecerParam(query, CAMPO_FECHAACTUALIZADA, filtro.getFechaActualizada());
			QueryUtil.establecerParam(query, CAMPO_ACTIVO, filtro.getActivo());
			QueryUtil.establecerParam(query, CAMPO_CODIGOUSUARIO, filtro.getCodigoUsuario() , true, true );
			QueryUtil.establecerParam(query, CAMPO_FECHAREGISTRO + QueryUtil.TOKEMN1, frinit);
			QueryUtil.establecerParam(query, CAMPO_FECHAREGISTRO + QueryUtil.TOKEMN2, frfin);
			QueryUtil.establecerParam(query, CAMPO_FECHAACTUALIZADA + QueryUtil.TOKEMN1, fainit);
			QueryUtil.establecerParam(query, CAMPO_FECHAACTUALIZADA + QueryUtil.TOKEMN2, fafin);
		
			if (logger.isDebugEnabled()){
				QueryUtil.printParameterQuery(query);
			}
		}
	
		
		public ResponsableDAOBaseUtil setFechaRegistro( Date  finit, Date  ffin ){
			createBuffer();
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_FECHAREGISTRO + QueryUtil.SQL_MENOS + QueryUtil.SQL_FILTRO + CAMPO_FECHAREGISTRO + QueryUtil.TOKEMN1), finit);
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_FECHAREGISTRO + QueryUtil.SQL_MAS + QueryUtil.SQL_FILTRO + CAMPO_FECHAREGISTRO + QueryUtil.TOKEMN2), ffin);
			this.frinit = finit;
			this.frfin = ffin;
			return this;
		}
		
		public ResponsableDAOBaseUtil setFechaActualizada( Date  finit, Date  ffin ){
			createBuffer();
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_FECHAACTUALIZADA + QueryUtil.SQL_MENOS + QueryUtil.SQL_FILTRO + CAMPO_FECHAACTUALIZADA + QueryUtil.TOKEMN1), finit);
			QueryUtil.establecerCondicion(strBuffer, (QueryUtil.SQL_SEA + CAMPO_FECHAACTUALIZADA + QueryUtil.SQL_MAS + QueryUtil.SQL_FILTRO + CAMPO_FECHAACTUALIZADA + QueryUtil.TOKEMN2), ffin);
			this.fainit = finit;
			this.fafin = ffin;
			return this;
			}
		
		@SuppressWarnings("unchecked")
		public List<Responsable> ejecutaFiltroFilas() throws DAOException {
			setFiltros();
			return query.getResultList();
		}
		
	
		@SuppressWarnings("unchecked")
		public List<Responsable> ejecutaFiltroFilas(int inicio, int fin, String strSort, String strOrder) throws DAOException {
			setFiltros();
			if ((inicio > - ConstantesUtil.NUMBER_0) && (fin > - ConstantesUtil.NUMBER_0)) {
				query.setFirstResult(inicio);
				query.setMaxResults(fin);
			}
			if (ValidateUtil.isNotNull(strSort) && ValidateUtil.isNotNull(strOrder)) {
				QueryUtil.setOrder(strBuffer, strSort, strOrder);
			}
			return query.getResultList();
		}
		
	
		public Responsable ejecutaFiltroPrimeraFila() throws DAOException {
			setFiltros();
			query.setFirstResult(1);
			query.setMaxResults(1);
			return  (Responsable) query.getSingleResult();
		}
	}

	private EntityManager getEntityManager() {
		 return entityManager;
	}
}
